package com.ygqh.baby.service.task.impl;

import com.foxinmy.weixin4j.mp.message.TemplateMessage;
import com.foxinmy.weixin4j.util.StringUtil;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.constant.Constant;
import com.ygqh.baby.exception.YgException;
import com.ygqh.baby.handler.SplitSendDetailHandler;
import com.ygqh.baby.model.YgGroupOrderRemindModel;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.*;
import com.ygqh.baby.service.impl.YgReturnOrderServiceImpl;
import com.ygqh.baby.service.task.YgBalanceTaskService;
import com.ygqh.baby.service.task.YgGroupBuyTaskService;
import com.ygqh.baby.service.wdtqyb.api.WdtQybApi;
import com.ygqh.baby.service.wechat.message.YgTemplateMessage;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.MailUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @author admin
 */
@Service
public class YgGroupBuyTaskServiceImpl implements YgGroupBuyTaskService {

    private final Logger logger = Logger.getLogger(YgReturnOrderServiceImpl.class);
    private final ExecutorService executorService = Executors.newFixedThreadPool(3);

    @Autowired
    private YgTaskTimeService ygTaskTimeService;
    @Autowired
    private YgGroupBuyingService ygGroupBuyingService;
    @Autowired
    private WxMpMessageService wxMpMessageService;
    @Autowired
    private WxSmallMessageService wxSmallMessageService;
    @Autowired
    private WdtQybApi wdtQybApi;
    @Autowired
    private YgUserService ygUserService;
    @Autowired
    private YgOrderService ygOrderService;
    @Autowired
    private YgOrderPaymentService ygOrderPaymentService;
    @Autowired
    private YgUserBalanceService ygUserBalanceService;
    @Autowired
    private YgReturnOrderService ygReturnOrderService;
    @Autowired
    private MailUtil mailUtil;
    @Autowired
    private YgOrderLogService ygOrderLogService;
    @Autowired
    private TrustoneService trustoneService;
    @Autowired
    private SplitSendDetailHandler splitSendDetailHandler;
    @Autowired
    private YgBalanceTaskService ygBalanceTaskService;

    @Value("${promotion.link}")
    protected String promotionLink;

    @Override
    public void groupOrderIncompleteReminder() {
        ygTaskTimeService.execute(TaskMethod.GroupOrderIncompleteReminder, TaskMethod.GroupOrderIncompleteReminder.getCode(), new YgTaskTimeTemplate() {

            @Autowired
            @Override
            public void execute(Date runTime) {
                Date startTime = DateConvertUtils.addMinute(runTime, -65);
                Date endTime = DateConvertUtils.addMinute(runTime, -60);
                List<YgGroupOrderRemindModel> list = ygGroupBuyingService.findGroupOrderIncompleteReminder(endTime, startTime, endTime);

                // List<TemplateMessage> msgList = new ArrayList<>();
                Date date = new Date();
                for (YgGroupOrderRemindModel model : list) {

                    String title = "亲，您的拼团商品 " + model.getProductName() + " 件数还不够哦。";
                    long[] times = DateConvertUtils.getDistanceTimes(date, model.getCompleteTime());
                    String lastTime = times[1] + "小时" + times[2] + "分钟";

                    Long lastAmount = 0L;
                    if (model.getGroupAmount() != null) {
                        lastAmount = model.getGroupAmount() - model.getFinishAmount();
                    }
                    if (lastAmount > 0) {

                        if (Constant.YIIGOO_PLATFORM_NO.equals(model.getPlatformNo())) {
                            // 到某团长页
                            String url = promotionLink + "/product/groupdetail.html?productId=" + model.getProductId() + "&tuanId=" + model.getGbId();
                            wxMpMessageService.sendGroupOrderRemindMsg(title, lastTime, lastAmount, url, model.getOrderUserId());
                        }

                        String formId = model.getFormId();
                        if (StringUtil.isNotBlank(formId)) {
                            wxSmallMessageService.sendGroupOrderRemindMsg(model.getProductName(), lastAmount,
                                    model.getCompleteTime(), model.getOrderId(), formId, model.getOrderUserId(),
                                    model.getPlatformNo());
                        }
                    }
                }
            }

        });

    }

    @Deprecated
    private void getGroupBuyRemindMsg(YgGroupOrderRemindModel model, Date runTime, List<TemplateMessage> msgList) {

        String title = "亲，您的拼团商品 " + model.getProductName() + " 件数还不够哦。";
        long[] times = DateConvertUtils.getDistanceTimes(new Date(), DateConvertUtils.addMinute(model.getGbCreateTime(), 12 * 60));
        String lastTime = times[1] + "小时" + times[2] + "分钟";
        Long lastAmount = 0L;
        if (model.getGroupAmount() != null) {
            lastAmount = model.getGroupAmount() - model.getFinishAmount();
        }
        if (lastAmount > 0) {
            // 到某团长页
            String url = promotionLink + "/product/groupdetail.html?productId=" + model.getProductId() + "&tuanId=" + model.getGbId();
            YgUser user = ygUserService.findById(model.getOrderUserId());
            if (StringUtil.isNotBlank(user.getOpenId())) {
                String wxMsgTempId = wxMpMessageService.getWxMsgTempId(WxMessageType.GroupOrderRemind);
                TemplateMessage wxMsg = new TemplateMessage(user.getOpenId(), wxMsgTempId, title, url);

                wxMsg.pushHead("#323232", title);
                wxMsg.pushItem("keyword1", "#323232", lastTime);
                wxMsg.pushItem("keyword2", "#323232", lastAmount + "人");
                wxMsg.pushItem("remark", "#323232", "快去分享给您的好友一起拼团吧. ");
                msgList.add(wxMsg);
            }

            String formId = model.getFormId();
            if (StringUtil.isNotBlank(formId) && StringUtil.isNotBlank(user.getSmallOpenId())) {
                String prompt = "快去分享给您的好友一起拼团吧.";
                Long orderId = model.getOrderId();
                String page = "pages/user/orderdetail/orderdetail?orderId=" + orderId;
                String wxMsgTempId = wxMpMessageService.getWxMsgTempId(WxMessageType.SmallGroupOrderRemind);
                TemplateMessage wxMsg = new YgTemplateMessage(user.getSmallOpenId(), wxMsgTempId, title, page, formId);
                wxMsg.pushHead("#323232", title);
                wxMsg.pushItem("keyword1", "#323232", model.getProductName());
                wxMsg.pushItem("keyword2", "#323232", lastAmount.toString());
                wxMsg.pushItem("keyword3", "#323232", DateConvertUtils.formatDateTime(model.getCompleteTime()));
                wxMsg.pushItem("keyword4", "#323232", prompt);

                msgList.add(wxMsg);
            }
        }

    }

    @Override
    public void groupOrderComplete() {
        ygTaskTimeService.execute(TaskMethod.GroupOrderComplete, TaskMethod.GroupOrderComplete.getCode(), new YgTaskTimeTemplate() {

            @Override
            public void execute(Date runTime) {

                List<Long> successOrderIds = null;
                List<Long> failOrderIds = null;
                Date startTime = DateConvertUtils.addMinute(runTime, -5);
                List<YgGroupOrderRemindModel> list = ygGroupBuyingService.findGroupBuy4Complete(startTime, runTime);

                Map<Long, List<YgGroupOrderRemindModel>> collect = list.stream().collect(Collectors.groupingBy(YgGroupOrderRemindModel::getGbId));
                List<TemplateMessage> msgList = new ArrayList<>();
                List<YgGroupBuying> completeList = null;
                List<YgGroupBuying> expireList = null;
                List<YgGroupOrderRemindModel> expireModelList = null;
                for (Long key : collect.keySet()) {

                    List<YgGroupOrderRemindModel> models = collect.get(key);

                    CompleteStatus status = getGroupBuyCompleteStatus(models.get(0), runTime);
                    // 完成拼团

                    List<Long> orderIds = new ArrayList<>();
                    List<YgGroupBuying> gbList = new ArrayList<>();
                    handleGroupBuyByStatus(status, models, runTime, gbList, orderIds, msgList);

                    if (CompleteStatus.Complete.equals(status)) {
                        if (completeList == null) {
                            completeList = new ArrayList<>();
                        }
                        if (successOrderIds == null) {
                            successOrderIds = new ArrayList<>();
                        }

                        completeList.addAll(gbList);
                        successOrderIds.addAll(orderIds);

                    } else {
                        if (expireList == null) {
                            expireList = new ArrayList<>();
                        }
                        if (failOrderIds == null) {
                            failOrderIds = new ArrayList<>();
                        }
                        if (expireModelList == null) {
                            expireModelList = new ArrayList<>();
                        }
                        expireModelList.addAll(models);
                        expireList.addAll(gbList);
                        failOrderIds.addAll(orderIds);
                    }

                }

                // 更新拼团状态
                ygGroupBuyingService.updateGbForCompleteBatch(completeList);
                ygGroupBuyingService.updateGbForExpireBatch(expireList);
                refund(expireModelList, failOrderIds);

                // 同步订单
                syncQybOrder(successOrderIds);

                // 发送消息
                sendWxMsg(msgList);

            }

        });
    }

    private final static BigDecimal ZERO = new BigDecimal("0.00");

    private void refund(List<YgGroupOrderRemindModel> expireModelList, List<Long> failOrderIds) {
        if (CollectionUtils.isEmpty(expireModelList)) {
            return;
        }

        logger.warn("拼团失败的订单：" + failOrderIds.toString());
        List<YgOrderPayment> orderPayListByAlipay = new ArrayList<>();
        for (YgGroupOrderRemindModel model : expireModelList) {

            try {
                if (model.getOrderId() == null) {
                    continue;
                }
                YgOrder order = ygOrderService.findByOrderId(model.getOrderId());
                if (OrderStatus.TradeClosed.equals(order.getOrderStatus())
                        || OrderStatus.WaitingPay.equals(order.getOrderStatus())) {
                    continue;
                }
                ygOrderService.closeOrderBySystem(order.getOrderId(), "拼团失败；");

                YgOrderPayment payment = ygOrderPaymentService.findByOrderId(order.getOrderId());
                if (payment != null && payment.getPaidPrice().doubleValue() > 0) {
                    try {
                        ygReturnOrderService.applyRefundNew(payment.getPlatformNo(), payment.getPayType(), payment.getAppType(), order.getOrderId().toString(), payment.getOrderPayCode(),
                                order.getTotalPrice(), order.getTotalPrice(), "系统");
                        ygOrderLogService.addOrderLog(Long.valueOf(payment.getOrderPayCode()), OrderStatus.TradeClosed, "系统", "拼团失败，自动退款");
                    } catch (Exception e) {
                        if (e instanceof YgException) {
                            orderPayListByAlipay.add(payment);
                            logger.error("订单拼团失败，支付宝支付，尚未退款；" + order.getOrderId(), e);
                            ygOrderLogService.addOrderLog(Long.valueOf(payment.getOrderPayCode()),
                                    OrderStatus.TradeClosed, "系统", "拼团失败，退款失败，暂不支持支付宝自动退款。");
                        } else {
                            throw e;
                        }
                    }
                }
                if (order.getAccountPrice().compareTo(ZERO) > 0) {
                    ygUserBalanceService.backAcountPrice(order.getUserId(), order.getAccountPrice());
                    ygUserBalanceService.addBalanceDetail(order.getUserId(), order.getOrderId().toString(),
                            order.getAccountPrice(), BalanceType.Balance,
                            OperationType.CancelOrder, "拼团失败", order.getPlatformNo());
                }

                List<YgReturnOrder> returnList = ygReturnOrderService.findRetrunByOrderId(order.getOrderId());
                List<String> returnCodeListByComplete = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(returnList)) {
                    for (YgReturnOrder ro : returnList) {
                        if (ro.getReturnType().equals(ReturnType.Return) && !ro.getReturnStatus().equals(ReturnStatus.Cancel)) {
                            ygReturnOrderService.cancelReturn(ro.getReturnCode(), "拼团未完成，已全部退款", "system");
                        }
                        if (ro.getReturnType().equals(ReturnType.Return) && ro.getReturnStatus().equals(ReturnStatus.Complete)) {
                            returnCodeListByComplete.add(ro.getReturnCode());
                        }
                    }
                }
                ygOrderLogService.addOrderLog(order.getOrderId(), OrderStatus.TradeClosed, "系统", "拼团失败，自动退款");
                // 退预收入
                ygBalanceTaskService.doCancelGroupOrder(order.getOrderId(), returnCodeListByComplete);
            } catch (YgException e) {
                logger.error(e.getMessage(), e);
                logger.error("处理拼团失败错误：" + model.toString());
            }
            if (CollectionUtils.isNotEmpty(orderPayListByAlipay)) {
                sendAlipayOrderMail(orderPayListByAlipay);
            }
        }

    }

    private void sendAlipayOrderMail(List<YgOrderPayment> orderPayListByAlipay) {
        executorService.execute(() -> {
            String to = "guohao@yiigoo.com,sunshuo@yiigoo.cn";
            StringBuilder str = new StringBuilder();
            str.append("<html><head>")
                    .append("<style>.table-d table{ background:#000;font-size:14px} .table-d table td{ background:#FFF} h5{width: auto;margin-right: 20px} .title{display: flex;line-height: 10px}</style>")
                    .append("</head><body>").append("<div class='table-d'>").append("<table width='800' border='0' cellspacing='1' cellpadding='0'>")
                    .append("<tr><td width='20%'>订单编号</td>" + "<td width='20%'>支付流水号</td>").append("<td width='20%'>支付宝交易流水号</td>")
                    .append("<td width='20%'>应支付价格</td>").append("<td width='20%'>已付价格</td>").append("<td width='20%'>支付成功时间</td></tr>");
            for (YgOrderPayment orderPay : orderPayListByAlipay) {
                str.append("<tr><td>").append(orderPay.getOrderId()).append("</td>").append("<td>").append(orderPay.getOrderPayCode()).append("</td>")
                        .append("<td>").append(orderPay.getTransactionId()).append("</td>").append("<td>").append(orderPay.getPrice()).append("</td>")
                        .append("<td>").append(orderPay.getPaidPrice()).append("</td>").append("<td>")
                        .append(DateConvertUtils.formatDateTime(orderPay.getPaySuccessTime())).append("</td></tr>");
            }
            str.append("</table>");
            try {
                mailUtil.sendWithHtml(to.split(","), DateConvertUtils.format(new Date()) + " 拼团失败，支付宝支付订单", str.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    private CompleteStatus getGroupBuyCompleteStatus(YgGroupOrderRemindModel model, Date runTime) {
        Long groupAmount = model.getGroupAmount() == null ? 0L : model.getGroupAmount();
        Long finishAmount = model.getFinishAmount();
        Date completeTime = model.getCompleteTime();

        CompleteStatus completeStatus = null;
        if (!model.getIsReal()) {
            completeStatus = CompleteStatus.Complete;
        } else if (groupAmount.compareTo(finishAmount) <= 0) {
            completeStatus = CompleteStatus.Complete;
        } else if (runTime.after(completeTime)) {
            completeStatus = CompleteStatus.Expire;
        }
        return completeStatus;
    }

    private void handleGroupBuyByStatus(CompleteStatus status, List<YgGroupOrderRemindModel> models, Date runTime, List<YgGroupBuying> groupBuyList,
                                        List<Long> orderIds, List<TemplateMessage> msgList) {
        Long gbId = models.get(0).getGbId();

        YgGroupBuying group = new YgGroupBuying(gbId, status, runTime);
        if (CompleteStatus.Complete.equals(status)) {
            group.setCompleteTime(runTime);
            for (YgGroupOrderRemindModel buy : models) {
                //TemplateMessage msg = getGroupOrderSuccessMsg(buy.getOrderUserId(), buy.getOrderId(), buy.getProductName(), buy.getTotalPrice());
//                if (msg != null) {
//                    msgList.add(msg);
//                }
                TemplateMessage smallMsg = wxSmallMessageService.getGroupOrderSuccessSmallMsg(buy.getOrderUserId(), buy.getOrderId(),
                        buy.getProductName(), buy.getTotalPrice(), buy.getPlatformNo(), buy.getCompleteTime());
                if (smallMsg != null) {
                    msgList.add(smallMsg);
                }
            }
        }
        List<Long> collect = models.stream().filter(m -> m.getOrderId() != null).map(YgGroupOrderRemindModel::getOrderId).collect(Collectors.toList());
        orderIds.addAll(collect);
        groupBuyList.add(group);

    }

    private void sendWxMsg(List<TemplateMessage> msgList) {
        if (CollectionUtils.isNotEmpty(msgList)) {
            executorService.execute(() -> msgList.forEach(msg -> {
                        if (msg instanceof YgTemplateMessage) {
                            wxSmallMessageService.sendTmplMsg((YgTemplateMessage) msg);
                        } else {
                            wxMpMessageService.sendTemplateMessage(msg);
                        }
                    }
            ));
        }
    }

    private void syncQybOrder(List<Long> orderIds) {
        if (CollectionUtils.isEmpty(orderIds)) {
            return;
        }
        executorService.execute(() -> {
            /*
             * 拼团成功，更新订单状态，WaitingCheck --> WaitingSend
             */
            for (Long orderId : orderIds) {
                ygOrderService.updateOrderStatusByOrderId(OrderStatus.WaitingSend, orderId);
                trustoneService.pushTrustonerOrderAndDeclareCustoms(orderId);
                splitSendDetailHandler.splitSendDetails(orderId);
            }
            wdtQybApi.tradePushByOrderIds(orderIds);
        });

    }

    @Deprecated
    private TemplateMessage getGroupOrderSuccessMsg(Long userId, Long orderId, String productName, BigDecimal orderPrice) {
        TemplateMessage tplMessage;
        YgUser user = ygUserService.findById(userId);
        if (user == null || StringUtil.isEmpty(user.getOpenId())) {
            return null;
        }
        String title = "亲，恭喜您在壹果拼团成功哦。";
        String remark = "点击进入订单详情页，查看订单信息。";
        String url = promotionLink + "/user/orderdetail.html?orderId=" + orderId;
        String tempId = wxMpMessageService.getWxMsgTempId(WxMessageType.GroupOrderComplete);
        tplMessage = new TemplateMessage(user.getOpenId(), tempId, title, url);
        tplMessage.pushHead("#323232", title);
        tplMessage.pushItem("keyword1", "#323232", productName);
        tplMessage.pushItem("keyword2", "#323232", "¥" + orderPrice);
        tplMessage.pushItem("remark", "#323232", remark);
        return tplMessage;

    }
}
